/***************************************************
> Copyright (C) 2025 ==LENA== All rights reserved.
> File Name: client.c
> Author: lena
> Mail:lena_li@126.com 
> Created Time: 2025年01月03日 星期五 16时32分43秒
***************************************************/
//客户端接收
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "cJSON.h"
int cnt = 0;
char ID[20];
struct sockaddr_in* seraddr;

// 函数声明
int sock_create(const char* server_addr,int port);
int regist(char phonenum[20], struct sockaddr_in *seraddr);
int logout(char phonenum[20], struct sockaddr_in *seraddr);
void judge_sequence_number(cJSON *json);
void judge_aut(cJSON *json);
void printf_data(cJSON *json);
void send_cnt(int cnt, struct sockaddr_in *seraddr);

//读取信息data
void printf_data(cJSON *json);

//申请补包
void send_cnt(int cnt,struct sockaddr_in *seraddr);


int sock_create(const char* server_addr,int port)
{
	//printf("111111\n");
	int sock = socket(AF_INET,SOCK_STREAM,0);
	//printf("111111\n");
	int ret = 0;
	if(sock == -1)
	{
		perror("socket");
		exit(-1);
	}
	//定义地址
	struct sockaddr_in *seraddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
	if (seraddr == NULL) 
	{
        perror("malloc");
        close(sock);
        return -1;
    }
	memset(seraddr,0,sizeof(struct sockaddr_in));

	seraddr->sin_family = AF_INET;
	//printf("111111\n");
	seraddr->sin_addr.s_addr = inet_addr(server_addr);
	//printf("111111\n");
	//htons：转化为可以java理解的
	seraddr->sin_port = htons(port);
	return sock;
}

void send_cnt(int cnt,struct sockaddr_in *seraddr)
{
	int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket");
        exit(-1);
    }

    // 连接服务器
    if (connect(sock, (struct sockaddr *)seraddr, sizeof(struct sockaddr_in)) == -1) {
        perror("connect");
        exit(-1);
    }

    cJSON *json = NULL;
    char type[20] = "resupply";
    json = cJSON_CreateObject();
    cJSON_AddItemToObject(json, "resupply", cJSON_CreateNumber(cnt));
    char *dest = NULL;
    dest = cJSON_Print(json);
    char buf[100] = {0};
    memcpy(buf, dest, strlen(dest));
    // 使用send函数发送数据，因为是TCP协议
    int ret = send(sock, buf, strlen(buf), 0);
    if (ret == -1) 
	{
        printf("send resupply");
        exit(-1);
    }
	printf("%d号补包已申请\n",cnt);
	cJSON_Delete(json);  // 释放cJSON对象占用的内存
    close(sock);
}

void printf_data(cJSON *json)
{
	cJSON *node = NULL;   
    node = cJSON_GetObjectItem(json, "data");
    if (node == NULL) 
	{
        printf("can't find data\n");
    }
    else if (node->type == cJSON_String) 
	{
        printf("%s\n",node->valuestring);		
    }
}

/*
函数名：judge_aut;判断授权信息
返回值：无;
参数：json;
*/

void judge_aut(cJSON *json)
{
	cJSON *node = NULL;
   
    node = cJSON_GetObjectItem(json, "authorization");
    if (node == NULL) 
	{
        printf("can't find authorization\n");
    }
    else if (node->type == cJSON_String) 
	{
        printf("本客户端的ID为%s\n",ID);
		char temp[20];
		//找到返回位置，没找到返回0；
		char* p = strstr(node->valuestring,ID);
		if(p != 0)
		{
			//判断序列号
			judge_sequence_number(json);
		}
	}
}

/*
函数名：judge_sequence_number;判断序列号是否依次递增
返回值：无;
参数：json;
*/

void judge_sequence_number(cJSON *json)
{
	cnt++;
	cJSON *node = NULL;
   
    node = cJSON_GetObjectItem(json, "sequence_number");
    if (node == NULL) 
	{
        printf("can't find sequence_number\n");
    }
    else if (node->type == cJSON_Number) 
	{
		int received_sequence_number = node->valueint;
        printf("收到的序列号为%d\n",received_sequence_number );
		if(cnt == received_sequence_number )
		{
			//读取信息data
			printf_data(json);
		}
        else
		{
			//申请补包(向服务器发送缺少包的序列号);
			send_cnt(cnt,seraddr);
		}
    }
}

int regist(char phonenum[100], struct sockaddr_in *seraddr) 
{
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) 
	{
        perror("socket");
        exit(-1);
    }

    // 连接服务器
    if (connect(sock, (struct sockaddr *)seraddr, sizeof(struct sockaddr_in)) == -1) 
	{
        perror("connect");
        exit(-1);
    }

    cJSON *json = NULL;
    char type[20] = "register";
    json = cJSON_CreateObject();
    cJSON_AddItemToObject(json, "type", cJSON_CreateString(type));
    cJSON_AddItemToObject(json, "phonenum", cJSON_CreateString(phonenum));
    char *dest = NULL;
    dest = cJSON_Print(json);
    char buf[100] = {0};
    memcpy(buf, dest, strlen(dest));
    // 使用send函数发送数据，因为是TCP协议
    int ret = send(sock, buf, strlen(buf), 0);
    if (ret == -1) 
	{
        printf("send register");
        exit(-1);
    }

    // 接收结果
    char result[100] = {0};
    memset(&result, 0, sizeof(result));
    // 使用recv函数接收数据，因为是TCP协议
    ret = recv(sock, result, sizeof(result), 0);
    if (ret == -1) 
	{
        printf("recv ID");
        exit(-1);
    }

    cJSON *node = NULL;
    json = cJSON_Parse(result);
    node = cJSON_GetObjectItem(json, "ID");
    if (node == NULL) 
	{
        printf("can't find ID\n");
		cJSON_Delete(json); 
        close(sock);
        return -1;
    }
    else if (node->type == cJSON_String) 
	{
        
        strcpy(ID, node->valuestring);
		cJSON_Delete(json); 
        close(sock);
        return atoi(ID); 
    }
	cJSON_Delete(json);
    close(sock);
    return -1;
}

// 注销函数
int logout(char phonenum[20], struct sockaddr_in *seraddr) {
    int res = 0;
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket");
        exit(-1);
    }

    // 连接服务器
    if (connect(sock, (struct sockaddr *)seraddr, sizeof(struct sockaddr_in)) == -1) {
        perror("connect");
        exit(-1);
    }

    cJSON *json = cJSON_CreateObject();
    char type[20] = "logout";
    cJSON_AddItemToObject(json, "type", cJSON_CreateString(type));
    cJSON_AddItemToObject(json, "phonenum", cJSON_CreateString(phonenum));
    char *dest = cJSON_Print(json);
    char buf[1024] = {0};
    strcpy(buf, dest);
    // 使用send函数发送数据
    int ret = send(sock, buf, strlen(buf), 0);
    if (ret == -1) {
        printf("send logout");
        exit(-1);
    }

    // 接收结果
    char result[1024] = {0};
    memset(&result, 0, sizeof(result));
    // 使用recv函数接收数据
    ret = recv(sock, result, sizeof(result), 0);
    if (ret == -1) {
        printf("recv res");
        exit(-1);
    }

    cJSON *node = cJSON_Parse(result);
    cJSON *res_node = cJSON_GetObjectItem(node, "res");
    if (res_node == NULL) {
        printf("can't find res\n");
        cJSON_Delete(node);
        close(sock);
        return -1;
    }
    else if (res_node->type == cJSON_Number) {
        res = res_node->valueint;
        cJSON_Delete(node);
        close(sock);
        return res;
    }
    cJSON_Delete(node);
    close(sock);
    return -1;
}

int main(int argc, const char* argv[]) {
   
	struct sockaddr_in *seraddr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
    if (seraddr == NULL) 
	{
        perror("malloc");
        return -1;
    }
	//printf("111111\n");
    // 调用sock_create函数创建套接字
    int sock = sock_create("127.0.0.1", 6868);
    if (sock == -1) 
	{
        printf("Failed to create socket.\n");
        return -1;
    }
//printf("111111\n");
    // 注册
    printf("是否注册？\n");
    printf("1---注册\n");
    printf("2---登录\n");
    printf("3---退出\n");
    printf("4---注销\n");
    printf("输入数字进行你的选择\n");
    int val = 0;
    scanf("%d", &val);

    switch (val)
    {
    case 1:
        char phonenum[20];
        printf("请输入你的注册号码\n");
        scanf("%s", phonenum);
        int ID = regist(phonenum, seraddr);
        // 注册失败处理
        while (ID == -1) {
            printf("请输入新的号码");
            scanf("%s", phonenum);
            ID = regist(phonenum, seraddr);
        }
        // 注册成功
        printf("%s用户已注册成功,您的登录密码为您的手机号\n", phonenum);
        break;
    case 2:
        if (ID == 0) 
		{
            printf("本客户端尚未注册,请注册后再尝试登录\n");
			break;
		}
        else 
		{
            char temp[20] = {0};
            printf("本客户端的ID为%d\n", ID);
            int tryTimes = 0;  // 记录已经尝试的次数
            while (tryTimes < 3) 
			{
                printf("请输入密码\n");
                scanf("%s", temp);
                if (strcmp(temp, phonenum) == 0)
					{
						printf("登陆成功\n");
						break;  // 登录成功，跳出循环
					}
                else {
                    tryTimes++;
                    if (tryTimes < 3) 
					{
                        printf("密码错误,请重新输入\n");
                    }
                    else 
					{
                        printf("密码错误次数过多，禁止再次输入！\n");
                    }
                }
            }
        }
        break;
    case 3:
        break;
    case 4:
        char temp[20] = {0};
        int res = 0;
        printf("请输入密码\n");
        scanf("%s", temp);
        res = logout(temp, seraddr);
        if (res == 1) {
            printf("注销成功\n");
        }
        else if (res == -1) {
            printf("注销失败\n");
        }
        break;
    default:
        break;
    }
	char pack[1024] = {0};
    memset(&pack, 0, sizeof(pack));
    // 使用recv函数接收数据
	int ret = 0;
    ret = recv(sock,pack, sizeof(pack), 0);
    if (ret == -1)
	{
        printf("recv pack\n");
        close(sock);
        exit(-1);
    }
	int res = 0;
	cJSON *json = NULL;
    cJSON *node = NULL;
    json = cJSON_Parse(pack);
    node = cJSON_GetObjectItem(json, "isreplenishment");
    if (node == NULL) {
        printf("can't find isreplenishment\n");
        return -1;
    }
    else if (node->type == cJSON_Number) {
        res = node->valueint;
		{
			if(res == 1)
			{
				
			}
			else if(res == 0)
			{
				//判断授权信息
				judge_aut(json);
			}			
		}
        close(sock);
        return res;
    }
	free(seraddr);
    close(sock);
    return 0;
}